package io.github.uicdb.et;

import io.github.uicdb.et.element.BasicElement;
import net.minecraft.core.Holder;
import net.minecraft.util.RandomSource;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.common.damagesource.DamageContainer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import top.theillusivec4.curios.api.CuriosCapability;
import top.theillusivec4.curios.api.type.capability.ICuriosItemHandler;

import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
import java.util.stream.Stream;

public class ModHelper {


    public static @Nullable LivingEntity findAttacker(@NotNull DamageContainer container) {
        var source = container.getSource();
        return findAttacker(source);
    }

    public static @Nullable LivingEntity findAttacker(DamageSource source) {
        LivingEntity attacker = null;
        if (!source.isDirect()) {
            if (source.getEntity() instanceof LivingEntity a) {
                attacker = a;
            }
        } else if (source.getDirectEntity() instanceof LivingEntity a) {
            attacker = a;
        }
        return attacker;
    }


    @Nullable
    public static <T> T randomSelect(List<T> list, RandomSource rand) {
        if (list == null || list.isEmpty()) return null;
        return list.get(rand.nextInt(list.size()));
    }

    @Nullable
    public static <T, U extends T> T randomSelectWithout(@NotNull Stream<U> list, @NotNull List<T> out, @NotNull RandomSource rand) {
        return randomSelect(list.filter(l -> !out.contains(l)).toList(), rand);
    }

    public static void findCurios(LivingEntity entity, Predicate<ItemStack> predicate, BiConsumer<LivingEntity, ICuriosItemHandler> consumer) {
        var curioCap = entity.getCapability(CuriosCapability.INVENTORY);
        if (curioCap != null) {
            //受伤传送
            var curio = curioCap.findFirstCurio(predicate);
            if (curio.isPresent()) {
                consumer.accept(entity, curioCap);
            }

        }
    }

    public static float calculateDamageModifier(BasicElement value, LivingEntity attacker, LivingEntity entity) {
        return ModAttributes.safeGetPrecent(value.getElementalObject().getIncreasing(), attacker);
    }

    public static int getElementAmount(LivingEntity target, Holder<BasicElement> value) {
        return IElementAttachment.getDataHandler(target).getAmount(ModElements.byHolder(value));
    }

    public static void attachElement(LivingEntity attacker, Holder<BasicElement> element, int amount, int ticks) {
        //todo 挂载元素
        if(attacker instanceof IElementAttachment attachment){
            attachment.elemental_theory_setElementData(attachment.elemental_theory_getElementData().set(ModElements.byHolder(element),amount,ticks,attacker));
        }
    }
}
